package com.interview.checkinfo.query;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;

import com.interview.checkinfo.entity.CheckInfo;
import com.interview.checkinfo.entity.CheckInfo_;

@Repository
public class CheckInfoQuery {
	@PersistenceContext
	EntityManager entityManager;

	protected Integer pageSize = 10;
	protected Integer pageIndex = 0;
	protected Integer total;

	protected String employeeName;
	protected Date createdStar;
	protected Date createdEnd;
	protected Date chcekInStar;
	protected Date checkInEnd;
	protected Date chcekOutStar;
	protected Date checkOutEnd;

	public Integer getPageSize() {
		return pageSize;
	}

	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}

	public Integer getPageIndex() {
		return pageIndex;
	}

	public void setPageIndex(Integer pageIndex) {
		this.pageIndex = pageIndex;
	}

	public Integer getTotal() {
		return total;
	}

	public void setTotal(Integer total) {
		this.total = total;
	}

	public String getEmployeeName() {
		return employeeName;
	}

	public void setEmployeeName(String employeeName) {
		this.employeeName = employeeName;
	}

	public Date getCreatedStar() {
		return createdStar;
	}

	public void setCreatedStar(Date createdStar) {
		this.createdStar = createdStar;
	}

	public Date getCreatedEnd() {
		return createdEnd;
	}

	public void setCreatedEnd(Date createdEnd) {
		this.createdEnd = createdEnd;
	}

	public Date getChcekInStar() {
		return chcekInStar;
	}

	public void setChcekInStar(Date chcekInStar) {
		this.chcekInStar = chcekInStar;
	}

	public Date getCheckInEnd() {
		return checkInEnd;
	}

	public void setCheckInEnd(Date checkInEnd) {
		this.checkInEnd = checkInEnd;
	}

	public Date getChcekOutStar() {
		return chcekOutStar;
	}

	public void setChcekOutStar(Date chcekOutStar) {
		this.chcekOutStar = chcekOutStar;
	}

	public Date getCheckOutEnd() {
		return checkOutEnd;
	}

	public void setCheckOutEnd(Date checkOutEnd) {
		this.checkOutEnd = checkOutEnd;
	}

	public List<CheckInfo> baseQuery() {

		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<CheckInfo> cq = cb.createQuery(CheckInfo.class);
		Root<CheckInfo> root = cq.from(CheckInfo.class);
		
		List<Predicate> queryCon = new ArrayList<Predicate>();
		
		if(this.employeeName != null){
			Predicate predicateName = cb.like(root.get(CheckInfo_.employeeName),
					"%" + employeeName + "%");
			queryCon.add(predicateName);
		}
		
		if(this.chcekInStar != null){
			Predicate checkInTimeBetween = cb.between(
					root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);
			queryCon.add(checkInTimeBetween);
		}
		
		cq.where(cb.and(queryCon.toArray(new Predicate[queryCon.size()])));
		
		/*
		
		
		

	
		
		
		Predicate createdTimeBetween = cb.between(
				root.get(CheckInfo_.createdTime), createdStar, createdEnd);

		Predicate checkInTimeBetween = cb.between(
				root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);

		Predicate chcekOutTimeBetween = cb.between(
				root.get(CheckInfo_.chcekOutTime), chcekOutStar, checkOutEnd);

		Predicate outTimeStar = cb.greaterThanOrEqualTo(
				root.get(CheckInfo_.chcekOutTime), chcekOutStar);

		Predicate outTimeEnd = cb.lessThanOrEqualTo(
				root.get(CheckInfo_.chcekOutTime), checkOutEnd);

		Predicate inTimeStar = cb.greaterThanOrEqualTo(
				root.get(CheckInfo_.createdTime), chcekInStar);

		Predicate inTimeEnd = cb.lessThanOrEqualTo(
				root.get(CheckInfo_.chcekInTime), checkInEnd);

		Predicate createdTimeStar = cb.greaterThanOrEqualTo(
				root.get(CheckInfo_.createdTime), createdStar);

		Predicate createdTimeEnd = cb.lessThanOrEqualTo(
				root.get(CheckInfo_.createdTime), createdEnd);
		
		if(this.employeeName != null){
			cb.and(predicateName);
		}
		
		if(this.chcekInStar != null){
			cb.and(checkInTimeBetween);
		}
		
		cq.where(predicateName);
		
		
		if (this.employeeName != null & this.chcekInStar != null
				& this.checkInEnd != null & this.chcekOutStar != null
				& this.checkOutEnd != null & this.createdStar != null
				& this.createdEnd != null) {
			Predicate createdTimeBetween = cb.between(
					root.get(CheckInfo_.createdTime), createdStar, createdEnd);
			Predicate checkInTimeBetween = cb.between(
					root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);
			cq.where(cb.and(predicateName, chcekOutTimeBetween,
					checkInTimeBetween, createdTimeBetween));

		} else if (this.employeeName == null & this.chcekInStar != null
				& this.checkInEnd != null & this.chcekOutStar != null
				& this.checkOutEnd != null & this.createdStar != null
				& this.createdEnd != null) {
			
			Predicate createdTimeBetween = cb.between(
					root.get(CheckInfo_.createdTime), createdStar, createdEnd);
			Predicate checkInTimeBetween = cb.between(
					root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);
			cq.where(cb.and(chcekOutTimeBetween, checkInTimeBetween,
					createdTimeBetween));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd != null & this.chcekOutStar != null
				& this.checkOutEnd != null & this.createdStar != null
				& this.createdEnd != null) {
			
			Predicate createdTimeBetween = cb.between(
					root.get(CheckInfo_.createdTime), createdStar, createdEnd);

			cq.where(cb.and(inTimeEnd, chcekOutTimeBetween, createdTimeBetween));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar != null
				& this.checkOutEnd != null & this.createdStar != null
				& this.createdEnd != null) {
			
			Predicate createdTimeBetween = cb.between(
					root.get(CheckInfo_.createdTime), createdStar, createdEnd);

			cq.where(cb.and(chcekOutTimeBetween, createdTimeBetween));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd != null & this.createdStar != null
				& this.createdEnd != null) {
			Predicate createdTimeBetween = cb.between(
					root.get(CheckInfo_.createdTime), createdStar, createdEnd);

			cq.where(cb.and(outTimeEnd, createdTimeBetween));

		} else if (this.employeeName != null & this.chcekInStar != null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(cb.and(predicateName, inTimeStar));

		} else if (this.employeeName != null & this.chcekInStar == null
				& this.checkInEnd != null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(cb.and(predicateName, inTimeEnd));

		} else if (this.employeeName != null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar != null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(cb.and(predicateName, outTimeStar));

		} else if (this.employeeName != null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd != null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(cb.and(predicateName, outTimeEnd));

		} else if (this.employeeName != null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar != null
				& this.createdEnd == null) {

			cq.where(cb.and(predicateName, createdTimeStar));

		} else if (this.employeeName != null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd != null) {

			cq.where(cb.and(predicateName, createdTimeEnd));

		} else if (this.employeeName != null & this.chcekInStar != null
				& this.checkInEnd != null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {
			
			Predicate checkInTimeBetween = cb.between(
					root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);
			cq.where(cb.and(predicateName, checkInTimeBetween));

		} else if (this.employeeName != null & this.chcekInStar != null
				& this.checkInEnd != null & this.chcekOutStar != null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {
			
			Predicate checkInTimeBetween = cb.between(
					root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);
			cq.where(cb.and(predicateName, checkInTimeBetween, outTimeStar));

		} else if (this.employeeName != null & this.chcekInStar != null
				& this.checkInEnd != null & this.chcekOutStar != null
				& this.checkOutEnd != null & this.createdStar == null
				& this.createdEnd == null) {
			
			Predicate checkInTimeBetween = cb.between(
					root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);
			cq.where(cb.and(predicateName, checkInTimeBetween,
					chcekOutTimeBetween));

		} else if (this.employeeName != null & this.chcekInStar != null
				& this.checkInEnd != null & this.chcekOutStar != null
				& this.checkOutEnd != null & this.createdStar != null
				& this.createdEnd == null) {
			
			Predicate checkInTimeBetween = cb.between(
					root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);
			cq.where(cb.and(predicateName, checkInTimeBetween,
					chcekOutTimeBetween, createdTimeStar));

		} else if (this.employeeName == null & this.chcekInStar != null
				& this.checkInEnd == null & this.chcekOutStar != null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(cb.and(inTimeStar, outTimeStar));

		} else if (this.employeeName == null & this.chcekInStar != null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd != null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(cb.and(inTimeStar, outTimeEnd));

		} else if (this.employeeName == null & this.chcekInStar != null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar != null
				& this.createdEnd == null) {

			cq.where(cb.and(inTimeStar, createdTimeStar));

		} else if (this.employeeName == null & this.chcekInStar != null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd != null) {

			cq.where(cb.and(inTimeStar, createdTimeEnd));

		} else if (this.employeeName == null & this.chcekInStar != null
				& this.checkInEnd != null & this.chcekOutStar != null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {
			
			Predicate checkInTimeBetween = cb.between(
					root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);
			
			cq.where(cb.and(checkInTimeBetween, outTimeStar));

		} else if (this.employeeName == null & this.chcekInStar != null
				& this.checkInEnd != null & this.chcekOutStar != null
				& this.checkOutEnd != null & this.createdStar == null
				& this.createdEnd == null) {
			
			Predicate checkInTimeBetween = cb.between(
					root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);
			
			cq.where(cb.and(checkInTimeBetween, chcekOutTimeBetween));

		} else if (this.employeeName == null & this.chcekInStar != null
				& this.checkInEnd != null & this.chcekOutStar != null
				& this.checkOutEnd != null & this.createdStar != null
				& this.createdEnd == null) {
			
			Predicate checkInTimeBetween = cb.between(
					root.get(CheckInfo_.chcekInTime), chcekInStar, checkInEnd);
			
			cq.where(cb.and(checkInTimeBetween, chcekOutTimeBetween,
					createdTimeStar));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd != null & this.chcekOutStar != null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(cb.and(inTimeEnd, outTimeStar));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd != null & this.chcekOutStar == null
				& this.checkOutEnd != null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(cb.and(inTimeEnd, outTimeEnd));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd != null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar != null
				& this.createdEnd == null) {

			cq.where(cb.and(inTimeEnd, createdTimeStar));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd != null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd != null) {

			cq.where(cb.and(inTimeEnd, createdTimeEnd));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar != null
				& this.checkOutEnd == null & this.createdStar != null
				& this.createdEnd == null) {

			cq.where(cb.and(outTimeStar, createdTimeStar));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar != null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd != null) {

			cq.where(cb.and(outTimeStar, createdTimeEnd));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd != null & this.createdStar != null
				& this.createdEnd == null) {

			cq.where(cb.and(outTimeEnd, createdTimeStar));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd != null & this.createdStar == null
				& this.createdEnd != null) {

			cq.where(cb.and(outTimeEnd, createdTimeEnd));

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar != null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(outTimeStar);

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd != null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(outTimeEnd);

		} else if (this.employeeName == null & this.chcekInStar != null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(inTimeStar);

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd != null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(inTimeEnd);

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar != null
				& this.createdEnd == null) {

			cq.where(createdTimeStar);

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar != null
				& this.createdEnd != null) {
			Predicate createdTimeBetween = cb.between(
					root.get(CheckInfo_.createdTime), createdStar, createdEnd);

			cq.where(createdTimeBetween);
		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd != null) {

			cq.where(createdTimeEnd);

		} else if (this.employeeName != null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(predicateName);

		} else if (this.employeeName == null & this.chcekInStar != null
				& this.checkInEnd != null & this.chcekOutStar == null
				& this.checkOutEnd == null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(checkInTimeBetween);

		} else if (this.employeeName == null & this.chcekInStar == null
				& this.checkInEnd == null & this.chcekOutStar != null
				& this.checkOutEnd != null & this.createdStar == null
				& this.createdEnd == null) {

			cq.where(chcekOutTimeBetween);

		} else {
			cq.where(predicateName);
		}
		*/
		this.total = entityManager.createQuery(cq).getResultList().size();

		Query query = entityManager.createQuery(cq).setFirstResult(pageIndex)
				.setMaxResults(pageSize);
		List<CheckInfo> checkInfoes = query.getResultList();
		return checkInfoes;
	}

}
